﻿package cz.dadul.adventure.model 
{
	import cz.dadul.adventure.model.Element;
	import flash.display.*;
	import flash.events.MouseEvent;
	import cz.dadul.adventure.model.events.*;
	
	/**
	 * ...
	 * @author Dadul
	 */
	public class PickableItem extends ClickableItem implements IPickable
	{
		public static const EVENT_PICK:String = "event.item.pick";
		public static const EVENT_PREPARE_TO_USE:String = "event.item.use";
		/* 3 types of after-usage events:
		*
		*  Use & dock 	- after the usage, the item is docked back to the itirenary
		*  Use & undock - after the usage, the item is undocked and put back to the stage
		*  Use & remove - after the usage, the item is undocked and removed completely
		*/ 
		public static const EVENT_USE_AND_DOCK:String = "event.item.use_and_dock";
		public static const EVENT_USE_AND_UNDOCK:String = "event.item.use_and_undock";
		public static const EVENT_USE_AND_REMOVE:String = "event.item.use_and_remove";

		public static const MAX_WIDTH:uint = 50;
		public static const TYPE_DOCKED:String = ":docked";
		
		public static const FRAME_PREFIX_PICK:String = "p";
		
		// Docked in the StorageController
		protected var _docked:Boolean;
		// Logic used for the item application in the game
		protected var _usableLogic:Array;
		
		public function PickableItem(name:String, mc:MovieClip)
		{
			super(name, mc);
			this._usableLogic = new Array();
			this._docked = false;
		}		
		
		/*
		 * Public functions
		 */		
		
		// Pick the item from the scene (MainLayer)
		public function pick():void {			
			dispatchEvent(new DataHolderEvent(EVENT_PICK, this));	
		}
			
		public function useAndDock():void {
			dispatchEvent(new DataHolderEvent(EVENT_USE_AND_DOCK, this));
		}
		
		public function useAndUndock():void {
			dispatchEvent(new DataHolderEvent(EVENT_USE_AND_UNDOCK, this));
		}

		public function useAndRemove():void {
			dispatchEvent(new DataHolderEvent(EVENT_USE_AND_REMOVE, this));
		}
		
		
		public function useOnTarget(targetItemName:String):Boolean {
			var used:Boolean = false;			
			if (this._usableLogic[targetItemName] != null) {
				if (this._usableLogic[targetItemName][this._state] != null) {
					// Hide itself before performLogic
					hide();
					performAction(this._usableLogic[targetItemName][this._state]);
					used = true;
				} else {
					if (this._logic[targetItemName][ElementActionSet.DEFAULT] != null) {
						// Hide itself before performLogic
						hide();
						performAction(this._usableLogic[targetItemName][ElementActionSet.DEFAULT]);
						used = true;
					} else {
						throw new Error("["+this.name+"] Missing default action for the target ["+targetItemName+"]!");
					}										
				}
			}
			return used;
		}
		
		public function useOnDockedTarget(targetItemName:String):Boolean {
			return useOnTarget(targetItemName + PickableItem.TYPE_DOCKED);
		}
		
		
		public function transformDocked(docked:String):void {
			/**
			 * TODO: Prepise :docked variable na novy
			 */
		}
		
		public override function enableFocus(enable: Boolean = true):void {
			// Perform only if the Item si not disabled (after usage for example)
			this._hitMovieClip.mouseEnabled = enable;			
		}
		
		
		/*
		 * Protected
		 */ 
		protected override function addTimelineBehaviour():void {
			// Call previous behaviour			
			super.addTimelineBehaviour();
			var action:Function = function(self:Element, frameName: String):Function {				
				return function():void {	
					self.stop();					
					self.dispatchEvent(new TimelineEvent(Element.EVENT_TIMELINE, this.name, frameName));
					// User-defined action
					PickableItem(self).pick();
				}
			}						
			addPrefixBehaviour(FRAME_PREFIX_PICK, action);			
		}
		 
		
		protected override function onClick(e:MouseEvent):void {
			if (!this._docked) {
				
				dispatchEvent(new DataHolderEvent(EVENT_CLICK, this));
				
				// Perform logic action if found
				if (this._clickableLogic[this._state] != null) {
					// try determined by the state
					performAction(this._clickableLogic[this._state]);
				} else if(this._clickableLogic[ElementActionSet.DEFAULT] != null) {
					// try the default logic
					performAction(this._clickableLogic[ElementActionSet.DEFAULT]);
				}				
			} else {
				// Item is docked in the StorageController -> prepare to use it on the other item
				this.prepareToUse();
			}
		}
		
		// Use the item from the Controller
		protected function prepareToUse():void {
			dispatchEvent(new DataHolderEvent(EVENT_PREPARE_TO_USE, this));
		}
		
		/*
		 * SETTERS / GETTERS
		 */ 
		public function set docked(b:Boolean):void {
			if (b) {
				this.content.gotoAndStop(TYPE_DOCKED);	
			} else {
				this.content.gotoAndStop(_state);
			}			
			this._docked = b;
		}
		public function get docked():Boolean {
			return this._docked;
		}		
		
		public function set usableLogic(l:Array):void {
			this._usableLogic = l;
		}
		public function get usableLogic ():Array {
			return this._usableLogic;
		}		
	}

}